/*
 * Copyright (C) 2011 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.common.util;

import java.util.ArrayList;

import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.Process;
import android.os.RemoteException;

import com.mol.market.Constants;
import com.mol.market.Session;
import com.mol.market.common.download.DownloadManager;
import com.mol.market.common.network.ApiAsyncTask.ApiRequestListener;
import com.mol.market.common.network.MarketAPI;
import com.mol.market.common.vo.DownloadItem;
import com.mol.market.common.vo.ProductDetail;

/**
 * 批量下载服务(云手机)
 * 
 * @author andrew.wang
 * @date   2011-11-23
 * @since Version 0.8.3
 */
public class BatchDownloadService extends Service implements ApiRequestListener {

    /**
     * 绑定客户端
     */
    private static final int REGISTER_CLIENT = 0;
    
    /**
     * 开始批量下载<br>
     * msg.obj -> 数据结构ArrayList<String>，产品ID列表
     */
    private static final int START_BATCH_DOWNLOAD = 1;
    
    /**
     * 开始单个下载任务
     */
    private static final int START_SINGLE_DOWNLOAD = 2;
    
    /**
     * 绑定成功
     */
    private static final int BIND_SUCCESS = 2;
    
    /**
     * 成功开始下载
     */
    private static final int START_DOWNLOAD = 4;
    
    /**
     * 收费应用
     */
    private static final int ERROR_PAID = 8;
    
    /**
     * 连接错误
     */
    private static final int ERROR_CONNECTION_FAIL = 16;
    
    /**
     * 请求产品ID列表
     */
    private static final String PRODUCT_ID_LIST = "list";
    
    /**
     * 请求下载结果
     */
    private static final String RESULT = "result";
    
    /**
     * 客户端消息接收器
     */

    private ArrayList<Messenger> mClientMessengers;
    
    /**
     * 会话信息
     */
    private Session mSession;
    
    private boolean mIsLoading;
    
    private String mCurrentTask;
    
    private ProductDetail mProduct;
    
    @Override
    public void onCreate() {
        super.onCreate();
        mClientMessengers = new ArrayList<Messenger>();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mClientMessengers = null;
    }
    
    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {

            case REGISTER_CLIENT: {

                if (mClientMessengers == null) {
                    mClientMessengers = new ArrayList<Messenger>();
                }
                
                Messenger client = msg.replyTo;
                mClientMessengers.add(client);
                mSession = Session.get(getApplicationContext());
                Message returnMsg = Message.obtain();
                returnMsg.what = BIND_SUCCESS;
                try {
                    client.send(returnMsg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            }
            case START_BATCH_DOWNLOAD: {

                Bundle data = (Bundle) msg.obj;
                handleBatchRequest(data.getStringArrayList(PRODUCT_ID_LIST));
                break;
            }
            case START_SINGLE_DOWNLOAD:
                
                MarketAPI.getProductDetailWithId(getApplicationContext(), BatchDownloadService.this,
                        -1, mCurrentTask, Constants.SOURCE_TYPE_GFAN);
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    
    /*
     * 处理产品列表
     */
    private void handleBatchRequest(final ArrayList<String> list) {
        
        if (list == null || list.size() <= 0) {
            return;
        }
        
        new Thread() {

            public void run() {
                
                setPriority(Process.THREAD_PRIORITY_BACKGROUND);
                
                mIsLoading = false;
                for (String id : list) {

                    mCurrentTask = id;
                    while (mIsLoading) {

                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    
                    try {
                        mMessenger.send(Message.obtain(null, START_SINGLE_DOWNLOAD));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }

                    synchronized (BatchDownloadService.this) {
                        mIsLoading = true;
                    }
                }
            };

        }.start();
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
    
    @Override
    public void onSuccess(int method, Object obj) {
        
        if (method == MarketAPI.ACTION_GET_PRODUCT_DETAIL) {
            mProduct = (ProductDetail) obj;

            if (Constants.PAY_TYPE_PAID == mProduct.getPayCategory()) {
                // 收费应用
                Message msg = Message.obtain();
                msg.what = ERROR_PAID;
                Bundle data = new Bundle();
                data.putString(RESULT, mCurrentTask);
                msg.obj = data;
                
                sendMessageToClients(msg);
                
                synchronized (BatchDownloadService.this) {
                    mIsLoading = false;
                }
            } else {
                MarketAPI.getDownloadUrl(getApplicationContext(), this, mProduct.getPid(),
                        Constants.SOURCE_TYPE_GFAN);
            }

        } else if (method == MarketAPI.ACTION_GET_DOWNLOAD_URL) {
            
            DownloadItem info = (DownloadItem) obj;
            
            startDownload(info);
            synchronized (BatchDownloadService.this) {
                mIsLoading = false;
            }
        }
    }

    @Override
    public void onError(int method, int statusCode) {
        
        Message msg = Message.obtain();
        msg.what = ERROR_CONNECTION_FAIL;
        Bundle data = new Bundle();
        data.putString(RESULT, mCurrentTask);
        msg.obj = data;
        
        sendMessageToClients(msg);
        
        synchronized (BatchDownloadService.this) {
            mIsLoading = false;
        }
    }
    
    /*
     * 往客户端发送消息
     */
    private void sendMessageToClients(Message msg) {

        if (mClientMessengers == null || mClientMessengers.size() <= 0) {
            return;
        }
        
        for (Messenger messenger : mClientMessengers) {
            try {
                messenger.send(msg);
            } catch (RemoteException e) {
                Utils.D("Send remote message error", e);
            }
        }
    }
    
    /**
     * 开始下载任务
     */
    private void startDownload(DownloadItem info) {
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(info.url));
        request.setPackageName(info.packageName);
        request.setTitle(mProduct.getName());
        request.setIconUrl(mProduct.getIconUrl());
        request.setMD5(info.fileMD5);
        request.setSourceType(com.mol.market.common.download.Constants.DOWNLOAD_FROM_MARKET);
        mSession.getDownloadManager().enqueue(getApplicationContext(), request, null);
        Message msg = Message.obtain();
        msg.what = START_DOWNLOAD;
        Bundle data = new Bundle();
        data.putString(RESULT, mCurrentTask);
        msg.obj = data;
        
        sendMessageToClients(msg);
    }

}
